package componentes.basicos;

/**
 * Esta classe representa um multiplexador de duas entradas.
 * Um multiplexador é capaz de selecionar
 * de suas entradas quais delas será enviadas para a saída.
 * 
 * @author Gustavo Miguel, Cleisson Alves, Evandro Francisco, Lucas.
 */
public class Multiplexador {
    
    /* Atributos da Classe */
    private Barramento[] entradas;
    private Barramento sinalOpr;
    private Barramento saida;
    
    /**
     * Cria um Multiplexador Padrão. Um multiplexador padrão possui 
     * apenas duas entradas e seus Barramentos iniciais são configurados
     * como inoperantes.
     * @see Barramento.
     */
    public Multiplexador() {
        
        this.entradas = new Barramento[2];
        this.sinalOpr = new Barramento(new Palavra());
        this.saida = new Barramento(new Palavra());
        
    }
    
    /**
     * Cria um Multiplexador com um número de entradas especificado.
     * Entretanto as entradas e o sinal de operação são configurados 
     * como inoperantes.
     * @param numEntradas Número de entradas.
     */
    public Multiplexador(int numEntradas) {
        
        this.entradas = new Barramento[numEntradas];
        this.sinalOpr = new Barramento(new Palavra());
        this.saida = new Barramento(new Palavra());
    }

    /**
     * Retorna o Barramento correspondente à saída do Multiplexador.
     * @return Barramento de saída.
     */
    public Barramento getSaida() {
        return saida;
    }

    /**
     * Retorna o Barramento correspondente ao sinal de operação do Multiplexador.
     * @return Barramento de sinal de operação.
     */
    public Barramento getSinalOpr() {
        return sinalOpr;
    }

    /**
     * Método para configurar as entradas de um multiplexador.
     * @param entradas Vetor com os barramentos de entradas.
     */
    public void setEntradas(Barramento[] entradas) {
        int numEntradas = entradas.length;
        if(numEntradas != this.entradas.length) {
            System.out.println("Entradas inconsistente para o Multiplexador");
            return;
        } 
        for(int i = 0; i < numEntradas; ++i) {
            this.entradas[i] = entradas[i];
        }
    }
    
    /**
     * Configura o Barramento do sinal de Operação do Multiplexador.
     * @param sinalOpr Barramento de sinal de Operação.
     */
    public void setSinalOpr(Barramento sinalOpr) {
        this.sinalOpr = sinalOpr;
    }
    
    
    /**
     * Configura a saida do multiplexador. A saída do Multiplexador
     * é configurada a partir do sinal de controle que especifica
     * qual das entradas deverá ser enviada para a saída.
     */
    public void setSaida() {
        int numEntradas = this.entradas.length;
        
        for(int i = 0; i < numEntradas; ++i) {
            if(sinalOpr.getBitsValor() == i) {
                saida.setBitsValor(entradas[i].getBitsValor());
            }
        }
    }

    
} // Fim da classe
